using System.Collections.Generic;

namespace System.Utility.Patterns
{
	public abstract class FlyweightBase<Tkey, TValue>
	where TValue : class
	{
		private static object _obj;

		protected static Dictionary<Tkey, TValue> Cache;

		public TValue this[Tkey key]
		{
			get
			{
				return GetInstance(key);
			}
		}

		static FlyweightBase()
		{
			_obj = new object();
			Cache = new Dictionary<Tkey, TValue>();
		}

		protected FlyweightBase()
		{
		}

		protected abstract void DoInitalize(Tkey key);

		public virtual TValue GetInstance(Tkey key)
		{
			Guard.ArgumentNotNull(key, "Tkey");
			lock (_obj)
			{
				if (!Cache.ContainsKey(key))
				{
					DoInitalize(key);
				}
			}
			return Cache[key];
		}
	}
}